package per.hnvcam.thread;

import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;

public class MultiTaskManager implements Runnable {
   private static final String DEFAULT_GROUP = "per.hnvcam.thread.MultiTaskManager";

   private static Map<String, MultiTaskManager> sharedInstances;
   private ThreadGroup threadGroup;
   private Queue<Task> taskList;
   private int maxThreads = 5;
   private int threadCount = 0;

   private MultiTaskManager(String group) {
      taskList = new ConcurrentLinkedQueue<Task>();
      threadGroup = new ThreadGroup(group);
   }

   public void addTask(Task task) {
      task.setPostProcessing(this);
      taskList.add(task);
      update();
   }

   public synchronized void run() {
      threadCount--;
      update();
   }

   private synchronized void update() {
      if (threadCount < maxThreads) {
         Task task = taskList.poll();
         if (task != null) {
            Thread thread = new Thread(threadGroup, task);
            threadCount++;
            thread.start();
         }
      }
   }

   public synchronized int getThreadCount() {
      return threadCount;
   }

   public static MultiTaskManager getInstance(String group) {
      if (sharedInstances == null) {
         sharedInstances = new HashMap<String, MultiTaskManager>();
      }
      if (!sharedInstances.containsKey(group)) {
         MultiTaskManager instance = new MultiTaskManager(group);
         sharedInstances.put(group, instance);
      }
      return sharedInstances.get(group);
   }

   public static MultiTaskManager getDefaultInstance() {
      return getInstance(DEFAULT_GROUP);
   }
}
